﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TSOL.FastSPWeb.ValueObjects;
using System.Threading;
using Microsoft.SharePoint;

namespace TSOL.FastSPWeb.Core
{
    internal partial class FastSPItemUpdateThreadWorkerQueue
    {
        internal Guid QueueCreateSubWeb(SPWeb Web, string strWebUrl, string strTitle, string strDescription, uint nLCID, string strWebTemplate, bool useUniquePermissions, bool bConvertIfThere)
        {
            Guid SiteGuid = Web.Site.ID;
            Guid WebGuid = Web.ID;
            SPUser CurrentSPUser = Web.CurrentUser;

            Guid _actionID = Guid.NewGuid();
            lock (locker)
            {
                taskQ.Enqueue(new FastCreateSubWebQueueClass()
                        {
                            UserUniqueID = CurrentSPUser.LoginName.GetHashCode().ToString(),
                            UserToken = Web.Site.SystemAccount.UserToken.CompareUser(CurrentSPUser.UserToken) ?
                                                  null :
                                                  CurrentSPUser.UserToken,
                            SiteGuid = SiteGuid,
                            WebGuid = WebGuid,
                            Action = FastUpdateAction.CreateSubWeb,
                            ActionID = _actionID,
                            WebUrl = strWebUrl,
                            Title = strTitle,
                            Description = strDescription,
                            LCDID = nLCID,
                            WebTemplateName = strWebTemplate,
                            UseUniquePermissions = useUniquePermissions,
                            ConvertIfThere = bConvertIfThere
                        });
                Monitor.Pulse(locker);
            }
            return _actionID;
        }

        internal void CreateSubWeb(FastCreateSubWebQueueClass updateItem)
        {
            int internalUpdateTries = 0;
            bool updateDone = false;
            List<Exception> ActionException = new List<Exception>();

            while (updateDone == false && internalUpdateTries < FastSPWebThreadWorkerQueue.GlobalSPItemUpdateThreadWorkerQueue.UpdateTries)
            {
                try
                {
                    if (updateItem.UserToken == null)
                    {
                        FastSPWebCall.OpenElevatedWeb(updateItem.SiteGuid, updateItem.WebGuid,
                            (_site, _web, hashCode) =>
                            {
                                using (SPWeb _subWeb = _web.Webs.Add(updateItem.WebUrl, updateItem.Title, updateItem.Description, updateItem.LCDID, updateItem.WebTemplateName, updateItem.UseUniquePermissions, updateItem.ConvertIfThere))
                                {
                                    lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.SiteDictionary)
                                    {
                                        int _urlHashCode = _subWeb.Site.Url.GetHashCode();
                                        SPSiteEntryClass _entry = null;

                                        if (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.SiteDictionary.TryGetValue(_urlHashCode, out _entry))
                                        {
                                            lock (_entry.WebDictionary) { 
                                                _entry.WebDictionary.Add(_subWeb.ServerRelativeUrl, _subWeb.ID);
                                            }
                                        }
                                        else
                                        {
                                            throw new Exception("Site not found in SiteDirectory dictionary, Site url: " + _subWeb.Site.Url);
                                        }

                                    }

                                }
                            });
                    }
                    else
                    {
                        FastSPWebCall.OpenWeb(updateItem.UserUniqueID, updateItem.UserToken, updateItem.SiteGuid, updateItem.WebGuid,
                            (_site, _web, hashCode) =>
                            {
                                using (SPWeb _subWeb = _web.Webs.Add(updateItem.WebUrl, updateItem.Title, updateItem.Description, updateItem.LCDID, updateItem.WebTemplateName, updateItem.UseUniquePermissions, updateItem.ConvertIfThere))
                                {
                                    lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.SiteDictionary)
                                    {
                                        int _urlHashCode = _subWeb.Site.Url.GetHashCode();
                                        SPSiteEntryClass _entry = null;

                                        if (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.SiteDictionary.TryGetValue(_urlHashCode, out _entry))
                                        {
                                            lock (_entry.WebDictionary)
                                            {
                                                _entry.WebDictionary.Add(_subWeb.ServerRelativeUrl, _subWeb.ID);
                                            }
                                        }
                                        else
                                        {
                                            throw new Exception("Site not found in SiteDirectory dictionary, Site url: " + _subWeb.Site.Url);
                                        }

                                    }

                                }
                            });
                    }
                    updateDone = true;
                }
                catch (Exception exception)
                {
                    ActionException.Add(exception);
                    internalUpdateTries++;
                }
            }

            if (!updateDone)
            {
                lock (FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.UpdateExceptionDictionary)
                {
                    FastSPWebThreadWorkerQueue.GlobalSPWebThreadWorkerQueue.UpdateExceptionDictionary.Add(
                            updateItem.ActionID,
                            new FastCreateSubWebExceptionEntity
                            {
                                Action = updateItem.Action,
                                ActionExceptionList = ActionException,
                                ActionID = updateItem.ActionID,
                                SiteGuid = updateItem.SiteGuid,
                                UserToken = updateItem.UserToken,
                                UserUniqueID = updateItem.UserUniqueID,
                                WebGuid = updateItem.WebGuid,
                                Description = updateItem.Description,
                                LCDID = updateItem.LCDID,
                                Title = updateItem.Title,
                                ConvertIfThere = updateItem.ConvertIfThere,
                                UseUniquePermissions = updateItem.UseUniquePermissions,
                                WebTemplateName = updateItem.WebTemplateName,
                                WebUrl = updateItem.WebUrl
                            });
                }
            }
        }
    }
}
